﻿using System.Web;
using DoNet.Helper;

namespace DoNet.Platform.BaiDu
{
    /// <summary>
    /// 百度Access Token
    /// </summary>
    public class TokenApi
    {
        /// <summary>
        /// 获取Access Token
        /// </summary>
        /// <param name="client_id">应用的API Key</param>
        /// <param name="client_secret">应用的Secret Key</param>
        /// <param name="code">用户授权后得到code </param>
        /// <param name="redirect_uri">该值必须与获取Authorization  Code时传递的“redirect_uri”保持一致。 </param>
        /// <returns></returns>
        public static ReturnData GetToken(string client_id, string client_secret, string code, string redirect_uri)
        {
            string reqUrl = CommonConfig.WebApiUrl_BaiDu + "/oauth/2.0/token?grant_type=authorization_code" + string.Format("&client_id={0}&client_secret={1}&code={2}&redirect_uri={3}", client_id, client_secret, code, HttpUtility.UrlEncode(redirect_uri));
            var result = HttpHelper.HttpGet(reqUrl);
            if (result.success)
            {
                var obj = JsonHelper.DeserializeObject<dynamic>(result.data);
                if (obj != null)
                {
                    /*
                    {  
                         "error":  "invalid_grant",  
                         "error_description":  "Invalid  authorization  code:  ANXxSNjwQDugOnqeikRMu2bKaXCdlLxn"   
                    }  
                    */
                    if (obj.error != null)
                    {
                        return new ReturnData()
                        {
                            success = false,
                            message = obj.error_description,
                            data = result.data
                        };
                    }
                    else
                    {
                        return result;
                    }
                }
                else
                {
                    return result;
                }
            }
            else
            {
                return result;
            }
        }

        /// <summary>
        /// 获取授权URL
        /// </summary>
        /// <param name="client_id">注册应用时获得的API Key。</param>
        /// <param name="redirect_uri">授权后要回调的URI，即接收Authorization Code的URI。如果用户在授权过程中取消授权，会回调该URI，并在URI末尾附上error=access_denied参数。对于无Web Server的应用，其值可以是“oob”，此时用户同意授权后，授权服务会将Authorization Code直接显示在响应页面的页面中及页面title中。非“oob”值的redirect_uri按照如下规则进行匹配：（1）如果开发者在“授权安全设置”中配置了“授权回调地址”，则redirect_uri必须与“授权回调地址”中的某一个相匹配； （2）如果未配置“授权回调地址”，redirect_uri所在域名必须与开发者注册应用时所提供的网站根域名列表或应用的站点地址（如果根域名列表没填写）的域名相匹配。授权回调地址配置请参考附录Ⅰ-1。</param>
        /// <param name="state">重定向后会带上state参数。建议开发者利用state参数来防止CSRF攻击。</param>
        /// <param name="scope">以空格分隔的权限列表，若不传递此参数，代表请求用户的默认权限。可填basic或mobile。</param>
        /// <param name="display">登录和授权页面的展现样式，默认为“page”，具体参数定义请参考附录Ⅰ-2。</param>
        /// <returns></returns>
        public static string GetAuthorizeUrl(string client_id, string redirect_uri, string state = "", string scope = "", string display = "")
        {
            /*
            参数名	类型	是否必须	描述
            response_type	string 	是 	固定为 code。
            client_id	string	是	注册应用时获得的API Key。
            redirect_uri	string	是	授权后要回调的URI，即接收Authorization Code的URI。如果用户在授权过程中取消授权，会回调该URI，并在URI末尾附上error=access_denied参数。对于无Web Server的应用，其值可以是“oob”，此时用户同意授权后，授权服务会将Authorization Code直接显示在响应页面的页面中及页面title中。非“oob”值的redirect_uri按照如下规则进行匹配：（1）如果开发者在“授权安全设置”中配置了“授权回调地址”，则redirect_uri必须与“授权回调地址”中的某一个相匹配； （2）如果未配置“授权回调地址”，redirect_uri所在域名必须与开发者注册应用时所提供的网站根域名列表或应用的站点地址（如果根域名列表没填写）的域名相匹配。授权回调地址配置请参考附录Ⅰ-1。
            scope	string	否	以空格分隔的权限列表，若不传递此参数，代表请求用户的默认权限。可填basic或mobile。
            display	string	否	登录和授权页面的展现样式，默认为“page”，具体参数定义请参考附录Ⅰ-2。
            state	string	否	重定向后会带上state参数。建议开发者利用state参数来防止CSRF攻击。
            force_login	int	否	如传递“force_login=1”，则加载登录页时强制用户输入用户名和口令，不会从cookie中读取百度用户的登陆状态。
            confirm_login	int	否	如传递“confirm_login=1”且百度用户已处于登陆状态，会提示是否使用已当前登陆用户对应用授权。
            login_type	string	否	如传递“login_type=sms”，授权页面会默认使用短信动态密码注册登陆方式。
            qrext_clientid	string	否	网盘扫码透传字段
            bgurl	string	否	二维码登录方式的背景图片url链接，需要encode
            qrcodeW	int	否	自定义二维码图片的宽度
            qrcodeH	int	否	自定义二维码图片的高度
            qrcode	int	否	如传递“qrcode=1”，登录授权页面将增加扫码登录入口；注：扫码登录入口点击跳转至二维码页面，目前支持PC、TV、音箱、watch、kindle
            qrloginfrom	string	否	扫码登录被扫码端设备类型；目前传参仅支持：pc、tv、speakers、watch、kindle；注：speakers为音箱的标志；说明：此配置仅支持display=tv时；
            userReg	int	否	如传递“qrcode=1”，扫码登录页配置“用户名登录”、“注册”入口；说明：此配置仅支持display=tv时；
            appTip	string	否	扫码登录页二维码底部提示文案，中文文案需encodeURIComponent('提示文案')；说明：此配置仅支持display=tv时；
            appName	string	否	扫码登录页二维码底部app文案配置，中文文案需encodeURIComponent('网盘App')；说明：此配置仅支持display=tv时；

            GET https://openapi.baidu.com/oauth/2.0/authorize?response_type=CODE&client_id=API_KEY&redirect_uri=REDIRECT_URI&scope=SCOPE&state=STATE
            */
            string param = string.Format("/oauth/2.0/authorize?response_type=code&client_id={0}&redirect_uri={1}", client_id, HttpUtility.UrlEncode(redirect_uri));
            if(!string.IsNullOrWhiteSpace(state))
            {
                param += string.Format("&state={0}", state);
            }
            if (!string.IsNullOrWhiteSpace(scope))
            {
                param += string.Format("&scope={0}", scope);
            }
            if (!string.IsNullOrWhiteSpace(display))
            {
                param += string.Format("&display={0}", display);
            }
            return CommonConfig.WebApiUrl_BaiDu + param;
        }

        /// <summary>
        /// 获取授权用户信息
        /// 获取access_token之后，开发者可以通过access_token拉取用户信息。 
        /// </summary>
        /// <param name="access_token">是 由上述步骤获取的OpenAPI接口调用凭证</param>
        /// <param name="get_unionid">否 需要获取unionid时，传递get_unionid = 1</param>
        /// <returns></returns>
        public static ReturnData GetUserInfo(string access_token, int get_unionid = 0)
        {
            string param = string.Format("?access_token={0}", access_token);
            if (get_unionid == 1)
            {
                param = string.Format("&get_unionid={0}", get_unionid);
            }
            string reqUrl = CommonConfig.WebApiUrl_BaiDu + "/rest/2.0/passport/users/getInfo" + param;
            var result = HttpHelper.HttpGet(reqUrl);
            if (result.success)
            {
                var obj = JsonHelper.DeserializeObject<dynamic>(result.data);
                if (obj != null)
                {
                    /*
                    {  
                         "error_code": "100",  
                         "error_msg": "Invalid parameter"   
                    } 
                    */
                    if (obj.error_code != null)
                    {
                        return new ReturnData()
                        {
                            success = false,
                            message = obj.error_msg,
                            data = result.data
                        };
                    }
                    else
                    {
                        return result;
                    }
                }
                else
                {
                    return result;
                }
            }
            else
            {
                return result;
            }
        }
    }
}
